var played = {}, playedalias = {}, setting = {},
        mysql = require('mysql'),
        http = require('http'),
        url = require('url'),
        crypto = require('crypto'),
        querystring = require('querystring'),
        config = require('./config.js'),
        calc = require('./kj-data/kj-calc-time.js'),
        exec = require('child_process').exec,
        execPath = process.argv.join(" "),
        parse = require('./kj-data/parse-calc-count.js');
        log4js = require('log4js');
        log4js.configure('./log4js.json');
        
require('./String-ext.js');
// 抛出未知出错时处理

var logger = log4js.getLogger();
logger.level = 'debug';
logger.debug("Some debug messages");
var LogFile_info = log4js.getLogger('info'); 

process.on('uncaughtException', function (e) {
    logger.error(e.stack);
});
function loginfo(msg) {
    logger.info(msg);
}



// 自动重启
if (config.restartTime) {
    setTimeout(function (exec, execPath) {
        exec(execPath);
        process.exit(0);
    }, config.restartTime * 3600 * 1000, exec, execPath);
}
var timers = {};		// 任务记时器列表
var encrypt_key = '8d60493138e4caed6fe5c5c19d4c427d';
var zjCount = 0;
var alias = '';
var animalsYear = '';
var LiRunLv = 0;
http.request = (function (_request) {
    return function (options, callback) {
        var timeout = options['timeout'],
                timeoutEventId;
        var req = _request(options, function (res) {
            res.on('end', function () {
                clearTimeout(timeoutEventId);
            });
            res.on('close', function () {
                clearTimeout(timeoutEventId);
            });
            res.on('abort', function () {
            });
            callback(res);
        });
        //超时
        req.on('timeout', function () {
            req.end();
        });
        //如果存在超时
        timeout && (timeoutEventId = setTimeout(function () {
            req.emit('timeout', {message: 'have been timeout...'});
        }, timeout));
        return req;
    };
})(http.request);
getPlayedFun(runTask);
getsetting();
function getPlayedFun(cb) {
    try {
        var client = createMySQLClient();
    } catch (err) {
        loginfo(err);
        return;
    }
    client.query("select id, ruleFun, alias from ssc_played", function (err, data) {
        if (err) {
            loginfo('读取玩法配置出错：' + err.message);
        } else {
            data.forEach(function (v) {
                played[v.id] = v.ruleFun;
                playedalias[v.id] = v.alias;
            });
            if (cb)
                cb();
        }
    });
    client.end();
}

function getsetting() {
    var client = createMySQLClient();

    client.query("select name, value from ssc_params;", function (err, data) {
        if (err) {
            loginfo('读取本年生肖配置出错：' + err.message);
        } else {
            data.forEach(function (v) {
                setting[v.name] = v.value;
            });
        }
    });
    client.end();
}

function runTask() {
    if (config.cp.length)
        config.cp.forEach(function (conf) {
            timers[conf.name] = {};
            timers[conf.name][conf.timer] = {timer: null, option: conf};
            try {
                if (conf.enable)
                    run(conf);
            } catch (err) {
                restartTask(conf, config.errorSleepTime);
            }
        });
}

function restartTask(conf, sleep, flag) {
    if (sleep <= 0)
        sleep = config.errorSleepTime;
    if (!timers[conf.name])
        timers[conf.name] = {};
    if (!timers[conf.name][conf.timer])
        timers[conf.name][conf.timer] = {timer: null, option: conf};

    if (flag) {
        var opt;
        for (var t in timers[conf.name]) {
            opt = timers[conf.name][t].option;
            clearTimeout(timers[opt.name][opt.timer].timer);
            timers[opt.name][opt.timer].timer = setTimeout(run, sleep * 1000, opt);
            loginfo('休眠' + sleep + '秒后从' + opt.source + '采集' + opt.title + '数据...');
        }
    } else {
        clearTimeout(timers[conf.name][conf.timer].timer);
        timers[conf.name][conf.timer].timer = setTimeout(run, sleep * 1000, conf);
        loginfo('休眠' + sleep + '秒后从' + conf.source + '采集' + conf.title + '数据...');
    }
}

function run(conf) {
    if (timers[conf.name][conf.timer].timer)
        clearTimeout(timers[conf.name][conf.timer].timer);
    loginfo('开始从' + conf.source + '采集' + conf.title + '数据');
    var option = JSON.parse(JSON.stringify(conf.option));
    //option.path+='?'+(new Date()).getTime();
    http.request(option, function (res) {
        var data = "";
        res.on("data", function (_data) {
            data += _data.toString();
        });
        res.on("end", function () {
            try {
                try {
                    data = conf.parse(data);
                } catch (err) {
                    throw('解析' + conf.title + '数据出错：' + err);
                }
                try {
                    //submitData(data, conf);
                    /*if(data.type=='51' || data.type=='2'){
                     liRunData(data, conf);
                     }else{
                     submitData(data, conf);
                     }*/
                    submitData(data, conf);
                } catch (err) {
                    throw('提交出错：' + err);
                }
            } catch (err) {
                loginfo('运行出错：%s，休眠%f秒'.format(err, config.errorSleepTime));
                restartTask(conf, config.errorSleepTime);
            }
        });

        res.on("error", function (err) {
            loginfo(err);
            restartTask(conf, config.errorSleepTime);
        });

    }).on('timeout', function (err) {
        loginfo('从' + conf.source + '采集' + conf.title + '数据超时');
        restartTask(conf, config.errorSleepTime);
    }).on("error", function (err) {
        // 一般网络出问题会引起这个错
        loginfo(err);
        restartTask(conf, config.errorSleepTime);

    }).end();
}

//}}}

function submitData(data, conf) {
    loginfo('提交从' + conf.source + '采集的' + conf.title + '第' + data.number + '数据：' + data.data);
    try {
        var client = createMySQLClient();
    } catch (err) {
        throw('连接数据库失败');
    }
    
    data.time = Math.floor((new Date(data.time)).getTime() / 1000);
    client.query("insert into ssc_data(type, time, number, data) values(?,?,?,?)", [data.type, data.time, data.number, data.data], function (err, result) {
        if (err) {
            // 普通出错
            if (err.errno == 1062) {
                // 数据已经存在
                // 正常休眠
                try {
                    sleep = calc[conf.name](data);
                    if (sleep < 0)
                        sleep = config.errorSleepTime * 1000;
                } catch (err) {
                    restartTask(conf, config.errorSleepTime);
                    return;
                }
                loginfo(conf['title'] + '第' + data.number + '期数据已经存在数据');
                restartTask(conf, sleep / 1000, true);

            } else {
                loginfo('运行出错：' + err.message);
                restartTask(conf, config.errorSleepTime);
            }
        } else if (result) {
            // 正常
            try {
                sleep = calc[conf.name](data);
            } catch (err) {
                loginfo('解析下期数据出错：' + err);
                restartTask(conf, config.errorSleepTime);
                return;
            }
            loginfo('写入' + conf['title'] + '第' + data.number + '期数据成功');
            restartTask(conf, sleep / 1000, true);
            
        } else {
            logger.error('未知运行出错');
            restartTask(conf, config.errorSleepTime);
        }
    });
    client.end();
}

function requestKj(type, number) {
    var option = {
        host: config.submit.host,
        path: '%s/%s/%s/%'.format(config.submit.path, type, number)
    }
    http.get(config.submit, function (res) {
    });
}

function createMySQLClient(multipleStatements) {
    try {
        if(multipleStatements==true) {
            config.dbinfo.multipleStatements= true;
        }
        connection = mysql.createConnection(config.dbinfo);
        connection.connect(function (err) {
            if (err) {
                logger.error('连接数据库失败：' + err);
            }
        })
        return connection;
    } catch (err) {
        logger.error('连接数据库失败：' + err);
        return false;
    }
}



function getdatetime() {
    var todayDate = new Date();
    var tdyear = todayDate.getFullYear();       //年
    var tdmonth = todayDate.getMonth() + 1;     //月
    var tdday = todayDate.getDate() - 1;            //日
    if (tdmonth < 10)
        tdmonth = "0" + tdmonth;
    if (tdday < 10)
        tdday = "0" + tdday;
    var todaytime = tdyear.toString() + tdmonth.toString() + tdday.toString();
    return todaytime;
}



// 前台添加数据接口
http.createServer(function (req, res) {
    loginfo('前台访问' + req.url);
    var data = '';
    req.on('data', function (_data) {
        data += _data;
    }).on('end', function () {
        data = querystring.parse(data);
        var msg = {};
//        var hash = crypto.createHash('md5');
//        hash.update(data.key);
//        if (encrypt_key == hash.digest('hex')) {
        if (encrypt_key ==data.key) {
            delete data.key;
            if (req.url == '/data/add') {
                submitDataInput(data);
            } else if (req.url == '/data/kj') {
                loginfo('Maleo温馨提示：正在执行重新计算开奖...');
                calcJ(data, true)
            }
        } else {
            msg.errorCode = 1;
            msg.errorMessage = '校验不通过';
        }
        res.writeHead(200, {"Content-Type": "text/json"});
        res.write(JSON.stringify(msg));
        res.end();
    });
}).listen(8899);

function submitDataInput(data) {
    loginfo('提交从前台录入第' + data.number + '数据：' + data.data);
    try {
        var client = createMySQLClient();
    } catch (err) {
        throw('连接数据库失败');
    }
    data.time = Math.floor((new Date(data.time)).getTime() / 1000);
    client.query("insert into ssc_data(type, time, number, data) values(?,?,?,?)", [data.type, data.time, data.number, data.data], function (err, result) {
        if (err) {
            // 普通出错
            if (err.number == 1062) {
                // 数据已经存在
                loginfo('第' + data.number + '期数据已经存在数据');
            } else {
                logger.error('运行出错：' + err.message);
            }
        } else if (result) {
            // 正常
            loginfo('写入第' + data.number + '期数据成功');
            
        } else {
            logger.error('未知运行出错');
        }
    });
    client.end();
}



